package com.mikao.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mikao.alipay.AliPay;
import com.mikao.constant.ErrorCode;
import com.mikao.dao.*;
import com.mikao.dto.bo.*;
import com.mikao.dto.vo.*;
import com.mikao.entity.*;
import com.mikao.service.AuthService;
import com.mikao.service.UserService;
import com.mikao.service.VerifyCodeService;
import com.mikao.util.*;
import com.mikao.wxpay.WxPay;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.persistence.criteria.Predicate;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.transaction.Transactional;
import java.text.DecimalFormat;
import java.util.*;

/**
 * @author kenny
 */

@Slf4j
@Service
public class UserServiceImpl implements UserService {

    private final AliPay aliPay = new AliPay();
    private UserDao userDao;
    private AuthService authService;
    private RedisTemplate<String, String> redisTemplate;
    private VerifyCodeService verifyCodeService;
    private BroadcastDao broadcastDao;
    private AdvDao advDao;
    private UserPointDao userPointDao;
    private UserTicketDao userTicketDao;
    private TicketDao ticketDao;
    private OrderDao orderDao;
    private GoodsDao goodsDao;
    private AddressDao addressDao;
    private UserBankDao userBankDao;
    private MoneyDetailDao moneyDetailDao;
    private PreTradeDao preTradeDao;

    public UserServiceImpl(UserDao userDao, AuthService authService, RedisTemplate<String, String> redisTemplate, VerifyCodeService verifyCodeService, BroadcastDao broadcastDao, AdvDao advDao, UserPointDao userPointDao, UserTicketDao userTicketDao, TicketDao ticketDao, OrderDao orderDao, GoodsDao goodsDao, AddressDao addressDao, UserBankDao userBankDao, MoneyDetailDao moneyDetailDao, PreTradeDao preTradeDao) {
        this.userDao = userDao;
        this.authService = authService;
        this.redisTemplate = redisTemplate;
        this.verifyCodeService = verifyCodeService;
        this.broadcastDao = broadcastDao;
        this.advDao = advDao;
        this.userPointDao = userPointDao;
        this.userTicketDao = userTicketDao;
        this.ticketDao = ticketDao;
        this.orderDao = orderDao;
        this.goodsDao = goodsDao;
        this.addressDao = addressDao;
        this.userBankDao = userBankDao;
        this.moneyDetailDao = moneyDetailDao;
        this.preTradeDao = preTradeDao;
    }

    @Override
    public BaseResult<String> getToken(Long id) {
        return new BaseResult<>(authService.createToken(id));
    }

    @Override
    public BaseResult<UserVo> login(UserBo userBo) {
        Map<String, Object> map = new HashMap<>(4);
        map.put("appid", "wx813ac11958aee71a");
        map.put("secret", "c6587ee8ffe5691785f5c86ccfb6eead");
        map.put("code", userBo.getCode());
        map.put("grant_type", "authorization_code");

        /*
         * 获取access_token
         */
        String responses = HttpUtil.sendGet("https://api.weixin.qq.com/sns/oauth2/access_token", map);
        JSONObject jsonObject = JSON.parseObject(responses);
        String openid = jsonObject.getString("openid");
        String access_token = jsonObject.getString("access_token");

        redisTemplate.opsForValue().set("access_token", access_token);

        /*
         * 获取用户信息
         */
        Map<String, Object> map1 = new HashMap<>(3);
        map1.put("access_token", access_token);
        map1.put("openid", openid);
        map1.put("lang", "zh_CN");
        String responses1 = HttpUtil.sendGet("https://api.weixin.qq.com/sns/userinfo", map1);
        JSONObject jsonObject1 = JSON.parseObject(responses1);
        String nickname = jsonObject1.getString("nickname");
        String headimgurl = jsonObject1.getString("headimgurl");

        log.info("昵称" + nickname);
        log.info(headimgurl);

        userBo.setImageUrl(headimgurl);
        userBo.setName(nickname);

        /*
         * 写入用户信息
         */
        User user;
        if (ObjectUtils.isEmpty(openid)) {
            return new BaseResult<>(ErrorCode.OPEN_ID_ERROR.getCode(), ErrorCode.OPEN_ID_ERROR.getMsg());
        }
        user = userDao.findByOpenId(openid);
        if (ObjectUtils.isEmpty(user)) {
            user = new User();
            BeanUtils.copyProperties(userBo, user);
            user.setOpenId(openid);
            user.setStatus(true);
            user.setMoney(0.0);
            user.setPoint(0);
            userDao.saveAndFlush(user);
        }

        String token = authService.createToken(user.getId());

        UserVo userVo = new UserVo();
        user.setName(userBo.getName());
        user.setImageUrl(userBo.getImageUrl());
        userDao.saveAndFlush(user);

        BeanUtils.copyProperties(user, userVo);
        userVo.setToken(token);

        return new BaseResult<>(userVo);
    }

    @Override
    public BaseResult getVerifyCode(String mobile) {
        if (!ObjectUtils.isEmpty(mobile)) {
            return verifyCodeService.sendVerifyCode(mobile);
        }
        return new BaseResult(ErrorCode.GET_PHONE_ERROR.getCode(), "请输入手机号!");
    }

    @Override
    public BaseResult bindPhone(PhoneForm phoneForm, Long userId) {
        VerifyCodeForm verifyCodeForm = new VerifyCodeForm();
        verifyCodeForm.setAccount(phoneForm.getMobile());
        verifyCodeForm.setPhoneCode(phoneForm.getCode());
        BaseResult checkVerifyCode = verifyCodeService.checkVerifyCode(verifyCodeForm);
        if (!checkVerifyCode.getCode().equals(ErrorCode.SUCCESS.getCode())) {
            System.out.println(checkVerifyCode.getCode());
            return new BaseResult(ErrorCode.PHONE_CODE_ERROR.getCode(), ErrorCode.PHONE_CODE_ERROR.getMsg());
        }
        User user = userDao.findOne(userId);
        user.setPhone(phoneForm.getMobile());
        userDao.saveAndFlush(user);
        return new BaseResult(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg());
    }

    @Override
    public BaseResult<IndexDto> index() {
        IndexDto indexDto = new IndexDto();

        String discount = "";
        List<Broadcast> images = broadcastDao.findAll();
        List<Adv> list = advDao.findAll();
        if (!ObjectUtils.isEmpty(list.get(0))) {
            discount = list.get(0).getImageUrl();
        }
        indexDto.setDiscount(discount);
        indexDto.setImages(images);

        return new BaseResult<>(indexDto);
    }

    @Override
    public BaseResult<UserVo> myInfo(Long userId) {
        UserVo userVo = new UserVo();
        User user = userDao.findOne(userId);
        if (ObjectUtils.isEmpty(user)) {
            return new BaseResult<>(ErrorCode.USER_NOT_EXIT.getCode(), ErrorCode.USER_NOT_EXIT.getMsg());
        }
        BeanUtils.copyProperties(user, userVo);
        return new BaseResult<>(userVo);
    }

    @Override
    public BaseResult<List<PointDto>> pointDetail(Long userId, Integer type) {
        List<UserPoint> list = userPointDao.findAllByTypeAndUserIdOrderByCreateTimeDesc(type, userId);
        if (ObjectUtils.isEmpty(list)) {
            return new BaseResult<>(ErrorCode.NULL_CONTENT.getCode(), ErrorCode.NULL_CONTENT.getMsg());
        }
        List<PointDto> pointDtos = new ArrayList<>();
        PointDto pointDto;

        for (UserPoint userPoint : list) {
            pointDto = new PointDto();
            BeanUtils.copyProperties(userPoint, pointDto);
            pointDtos.add(pointDto);
        }
        return new BaseResult<>(pointDtos);
    }

    @Override
    @Transactional(rollbackOn = Exception.class)
    public BaseResult getTicket(Long userId, TicketForm ticketForm) {
        User user = userDao.findOne(userId);
        if (ObjectUtils.isEmpty(user)) {
            return new BaseResult(ErrorCode.USER_NOT_EXIT.getCode(), ErrorCode.USER_NOT_EXIT.getMsg());
        }
        UserTicket userTicket = userTicketDao.findAllByUserIdAndAndTicketIdAndStatus(userId, ticketForm.getTicketId(), false);
        if (!ObjectUtils.isEmpty(userTicket)) {
            return new BaseResult(ErrorCode.GOTTED_TICKET.getCode(), ErrorCode.GOTTED_TICKET.getMsg());
        }
        /*
         * 添加优惠券领取记录
         */
        UserTicket userTicket1 = new UserTicket();
        userTicket1.setUserId(userId);
        userTicket1.setTicketId(ticketForm.getTicketId());
        userTicket1.setStatus(false);
        userTicketDao.saveAndFlush(userTicket1);

        /*
         * 减少优惠券剩余数量
         */
        Ticket ticket = ticketDao.findOne(ticketForm.getTicketId());
        if (!ObjectUtils.isEmpty(ticket)) {
            ticket.setNum(ticket.getNum() - 1);
        }
        ticketDao.saveAndFlush(ticket);
        return new BaseResult(ErrorCode.SUCCESS.getCode(), "领取成功");
    }


    @Override
    public BaseResult<List<OrderDto>> getMyOrder(Long userId, Integer type, Date createTime, int size) {
        List<OrderDto> dtos = new ArrayList<>();
        OrderDto orderDto;

        Page<Orders> pages = orderDao.findAll((root, criteriaQuery, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            Predicate predicate1;
            Predicate predicate2;
            Predicate predicate3;
            if (ObjectUtils.isEmpty(createTime)) {
                predicate1 = criteriaBuilder.lessThan(root.get("createTime").as(Date.class), new Date());
            } else {
                predicate1 = criteriaBuilder.lessThan(root.get("createTime").as(Date.class), createTime);
            }
            if (!ObjectUtils.isEmpty(type)) {
                predicate2 = criteriaBuilder.equal(root.get("type").as(Integer.class), type);
                predicates.add(predicate2);
            }
            predicate3 = criteriaBuilder.equal(root.get("userId").as(Integer.class), userId);
            predicates.add(predicate1);
            predicates.add(predicate3);
            return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
        }, new PageRequest(0, size, new Sort(Sort.Direction.DESC, "createTime")));

        Goods goods;
        for (Orders order : pages.getContent()) {
            orderDto = new OrderDto();
            goods = goodsDao.findOne(order.getGoodsId());
            BeanUtils.copyProperties(goods, orderDto);
            BeanUtils.copyProperties(order, orderDto);
            orderDto.setGoodsId(goods.getId());
            dtos.add(orderDto);
        }
        if (dtos.size() == 0) {
            return new BaseResult<>(ErrorCode.NULL_CONTENT.getCode(), ErrorCode.NULL_CONTENT.getMsg());
        }
        return new BaseResult<>(dtos);
    }

    @Override
    public BaseResult<OrderDetailDto> getOrderDetail(Long id) {
        OrderDetailDto dto = new OrderDetailDto();
        Orders orders = orderDao.findOne(id);
        if (!ObjectUtils.isEmpty(orders)) {
            if (!ObjectUtils.isEmpty(orders.getAddressId())) {
                Address address = addressDao.findOne(orders.getAddressId());
                dto.setReceiverName(address.getReceiverName());
                dto.setReceiverPhone(address.getReceiverPhone());
                dto.setAddress(address.getProvince() + address.getCity() + address.getArea() + address.getAddress());
            }
            dto.setNum(orders.getNum());
            Goods goods = goodsDao.findOne(orders.getGoodsId());
            BeanUtils.copyProperties(goods, dto);
            if (!ObjectUtils.isEmpty(orders.getTicketId())) {
                Ticket ticket = ticketDao.findOne(orders.getTicketId());
                dto.setTicket(ticket.getPrice());
            } else {
                dto.setTicket(0);
            }
            dto.setOrdersId(id);
            dto.setCreateTime(orders.getCreateTime());
        }
        return new BaseResult<>(dto);
    }

    @Override
    public BaseResult<List<AddressDto>> getMyAddress(Long userId) {
        List<Address> list = addressDao.findAllByUserIdOrderByCreateTimeDesc(userId);
        List<AddressDto> dtos = new ArrayList<>();
        AddressDto dto;
        for (Address address : list) {
            dto = new AddressDto();
            BeanUtils.copyProperties(address, dto);
            dtos.add(dto);
        }
        return new BaseResult<>(dtos);
    }

    @Override
    public BaseResult sureOrder(Long userId, SureOrderForm sureOrderForm) {
        Orders orders = orderDao.findAllByUserIdAndGoodsIdAndTypeOrderByCreateTimeDesc(userId, sureOrderForm.getGoodsId(), 3);
        if (ObjectUtils.isEmpty(orders)) {
            return new BaseResult(ErrorCode.NULL_CONTENT.getCode(), "未找到相关订单！");
        }
        orders.setType(4);
        orderDao.saveAndFlush(orders);
        return new BaseResult(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg());
    }

    @Override
    public BaseResult pay(Long userId, PayForm payForm) {
        HttpServletResponse httpResponse = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getResponse();
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        java.text.DecimalFormat df = new DecimalFormat("0");
        String ip = "121.35.3.131";
        PreTrade preTrade;
        if (request.getHeader("x-forwarded-for") == null) {
            ip = request.getRemoteAddr();
        } else {
            ip = request.getHeader("x-forwarded-for");
        }
        //微信
        if ("1".equals(payForm.getType())) {
            User user = userDao.findOne(userId);
            String openid = user.getOpenId();
            String nonce_str = WXPayUtil.generateNonceStr();

            Map<String, String> data = new HashMap<>();
            data.put("openid", openid);
            data.put("appid", WxPay.appid);
            data.put("mch_id", WxPay.mch_id);
            data.put("nonce_str", nonce_str);
            data.put("body", WxPay.body);
            data.put("notify_url", "http://plant.mikao1688.com/plant_api/goods/changeOrder");
            data.put("trade_type", WxPay.trade_type);
            data.put("total_fee", df.format(Double.valueOf(payForm.getTotal_fee())*100).toString());
            data.put("out_trade_no", String.valueOf(payForm.getOrderId()));
            data.put("spbill_create_ip", ip);

            try {
                String sign = WXPayUtil.generateSignature(data, WxPay.secret);
                data.put("sign", sign);

                String xml = WXPayUtil.mapToXml(data);
                String responses = HttpUtil.sendPost(WxPay.ufdoder_url, xml);

                Map<String, String> map = WXPayUtil.xmlToMap(responses);
                String prepay_id = map.get("prepay_id");

                Map<String, String> data1 = new HashMap<>();
                data1.put("appId", WxPay.appid);
                data1.put("timeStamp", String.valueOf(WXPayUtil.getCurrentTimestamp()));
                data1.put("nonceStr", nonce_str);
                data1.put("signType", "MD5");
                data1.put("package", "prepay_id=" + prepay_id);

                String paySign = WXPayUtil.generateSignature(data1, WxPay.secret, WXPayConstants.SignType.MD5);
                data1.put("paySign", paySign);

                System.out.println(data1);
                return new BaseResult(data1);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        //支付宝
        if ("2".equals(payForm.getType())) {
            preTrade = new PreTrade();
            preTrade.setAmount(Double.valueOf(payForm.getTotal_fee()));
            preTrade.setOutTradeNo(String.valueOf(payForm.getOrderId()));
            preTrade.setType(1);//类型1 水果
            preTrade.setBalanceId(userId);
            preTrade.setPlatform(2);//支付宝
            preTrade.setStatus(false);
            preTradeDao.saveAndFlush(preTrade);
            return new BaseResult(aliPay.aliPay(String.valueOf(payForm.getOrderId()), "支付商品", "问鼎商城支付商品", String.valueOf(payForm.getTotal_fee())));
        }

        return null;
    }

    @Override
    public BaseResult addBankCard(Long userId, BankCardForm bankCardForm) {
        UserBank bank;
        bank = userBankDao.findAllByUserId(userId);
        if (!ObjectUtils.isEmpty(bank)) {
            BeanUtils.copyProperties(bankCardForm, bank);
            userBankDao.saveAndFlush(bank);
        } else {
            bank = new UserBank();
            BeanUtils.copyProperties(bankCardForm, bank);
            bank.setUserId(userId);
            userBankDao.saveAndFlush(bank);
        }
        return new BaseResult(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg());
    }

    @Override
    @Transactional(rollbackOn = Exception.class)
    public BaseResult withdraw(Long userId, WithdrawForm withdrawForm) {
        UserBank bank = userBankDao.findAllByUserId(userId);
        if (ObjectUtils.isEmpty(bank)) {
            return new BaseResult(ErrorCode.NULL_CONTENT.getCode(), "该用户未绑定银行卡");
        }
        User user = userDao.findOne(userId);
        if (user.getMoney() < withdrawForm.getMoney()) {
            return new BaseResult(ErrorCode.PARAM_ERROR.getCode(), "余额不足");
        }

        //减掉余额
        user.setMoney(user.getMoney() - withdrawForm.getMoney());

        //添加资金记录
        MoneyDetail moneyDetail = new MoneyDetail();
        moneyDetail.setUserId(userId);
        moneyDetail.setIntroduce("银行卡提现");
        moneyDetail.setMoney(withdrawForm.getMoney());
        moneyDetail.setType(1);
        moneyDetailDao.saveAndFlush(moneyDetail);
        return new BaseResult(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg());
    }

    @Override
    public BaseResult charge(Long userId, PayForm payForm) {
        PreTrade preTrade;
        Long stemp = Utils.getTimestamp();
        String nowTimeStrForSeconds = Utils.getNowTimeStrForSeconds();

        //微信
        if ("1".equals(payForm.getType())) {
            User user = userDao.findOne(userId);
            String openid = user.getOpenId();
            String nonce_str = WXPayUtil.generateNonceStr();
            java.text.DecimalFormat df = new DecimalFormat("0");
            Map<String, String> data = new HashMap<>();
            data.put("openid", openid);
            data.put("appid", WxPay.appid);
            data.put("mch_id", WxPay.mch_id);
            data.put("nonce_str", nonce_str);
            data.put("body", WxPay.body);
            data.put("notify_url", "http://plant.mikao1688.com/plant_api/user/addMoney");
            data.put("trade_type", WxPay.trade_type);
            data.put("total_fee", df.format(Double.valueOf(payForm.getTotal_fee())*100).toString());

            data.put("out_trade_no", nowTimeStrForSeconds);
            data.put("spbill_create_ip", "121.35.3.131");

            try {
                String sign = WXPayUtil.generateSignature(data, WxPay.secret);
                data.put("sign", sign);

                String xml = WXPayUtil.mapToXml(data);
                String responses = HttpUtil.sendPost(WxPay.ufdoder_url, xml);

                Map<String, String> map = WXPayUtil.xmlToMap(responses);
                String prepay_id = map.get("prepay_id");

                Map<String, String> data1 = new HashMap<>();
                data1.put("appId", WxPay.appid);
                data1.put("timeStamp", String.valueOf(WXPayUtil.getCurrentTimestamp()));
                data1.put("nonceStr", nonce_str);
                data1.put("signType", "MD5");
                data1.put("package", "prepay_id=" + prepay_id);

                String paySign = WXPayUtil.generateSignature(data1, WxPay.secret, WXPayConstants.SignType.MD5);
                data1.put("paySign", paySign);
                preTrade = new PreTrade();
                preTrade.setAmount(Double.valueOf(payForm.getTotal_fee()));
                preTrade.setOutTradeNo(nowTimeStrForSeconds);
                preTrade.setType(2);//类型1 充值余额
                preTrade.setBalanceId(userId);
                preTrade.setPlatform(1);//微信
                preTrade.setStatus(false);
                preTradeDao.saveAndFlush(preTrade);
                return new BaseResult(data1);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        //支付宝
        if ("2".equals(payForm.getType())) {
            preTrade = new PreTrade();
            preTrade.setAmount(Double.valueOf(payForm.getTotal_fee()));
            preTrade.setOutTradeNo(nowTimeStrForSeconds);
            preTrade.setType(2);//类型1 充值余额
            preTrade.setBalanceId(userId);
            preTrade.setPlatform(2);//支付宝
            preTrade.setStatus(false);
            preTradeDao.saveAndFlush(preTrade);
            return new BaseResult(aliPay.aliPay(nowTimeStrForSeconds, "支付商品", "问鼎商城支付商品", String.valueOf(payForm.getTotal_fee())));
        }
        return null;
    }

    @Override
    public BaseResult<List<MoneyDetailDto>> moneyDetail(Long userId, Integer type) {
        List<MoneyDetail> list = moneyDetailDao.findAllByUserIdAndTypeOrderByCreateTimeDesc(userId, type);
        List<MoneyDetailDto> dtos = new ArrayList<>();
        MoneyDetailDto dto;
        for (MoneyDetail moneyDetail : list) {
            dto = new MoneyDetailDto();
            BeanUtils.copyProperties(moneyDetail, dto);
            dtos.add(dto);
        }
        return new BaseResult<>(dtos);
    }


    public BaseResult payTree(Long userId, PayForm payForm) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        PreTrade preTrade;
        Long stemp = Utils.getTimestamp();
        java.text.DecimalFormat df = new DecimalFormat("0");
        String ip = "121.35.3.131";
        if (request.getHeader("x-forwarded-for") == null) {
            ip = request.getRemoteAddr();
        } else {
            ip = request.getHeader("x-forwarded-for");
        }
        //微信
        if ("1".equals(payForm.getType())) {
            User user = userDao.findOne(userId);
            String openid = user.getOpenId();
            String nonce_str = WXPayUtil.generateNonceStr();

            Map<String, String> data = new HashMap<>();
            data.put("openid", openid);
            data.put("appid", WxPay.appid);
            data.put("mch_id", WxPay.mch_id);
            data.put("nonce_str", nonce_str);
            data.put("body", WxPay.body);
            data.put("notify_url", "http://plant.mikao1688.com/plant_api/goods/changeTreeOrder");
            data.put("trade_type", WxPay.trade_type);
            data.put("total_fee", df.format(Double.valueOf(payForm.getTotal_fee())*100).toString());
            data.put("out_trade_no", String.valueOf(payForm.getOrderId())+String.valueOf(stemp));
            data.put("spbill_create_ip", ip);

            try {
                String sign = WXPayUtil.generateSignature(data, WxPay.secret);
                data.put("sign", sign);

                String xml = WXPayUtil.mapToXml(data);
                String responses = HttpUtil.sendPost(WxPay.ufdoder_url, xml);

                Map<String, String> map = WXPayUtil.xmlToMap(responses);
                String prepay_id = map.get("prepay_id");

                Map<String, String> data1 = new HashMap<>();
                data1.put("appId", WxPay.appid);
                data1.put("timeStamp", String.valueOf(WXPayUtil.getCurrentTimestamp()));
                data1.put("nonceStr", nonce_str);
                data1.put("signType", "MD5");
                data1.put("package", "prepay_id=" + prepay_id);

                String paySign = WXPayUtil.generateSignature(data1, WxPay.secret, WXPayConstants.SignType.MD5);
                data1.put("paySign", paySign);

                System.out.println(data1);
                return new BaseResult(data1);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        //支付宝
        if ("2".equals(payForm.getType())) {
            preTrade = new PreTrade();
            preTrade.setAmount(Double.valueOf(payForm.getTotal_fee()));
            preTrade.setOutTradeNo(String.valueOf(payForm.getOrderId())+String.valueOf(stemp));
            preTrade.setType(3);//类型1 支付树苗
            preTrade.setBalanceId(userId);
            preTrade.setPlatform(2);//支付宝
            preTrade.setStatus(false);
            preTradeDao.saveAndFlush(preTrade);
            return new BaseResult(aliPay.aliPay(String.valueOf(payForm.getOrderId()), "支付商品", "问鼎商城支付商品", String.valueOf(payForm.getTotal_fee())));
        }

        return null;
    }

    @Override
    public BaseResult addMyAddress(Long userId, AddressForm addressForm) {
        Address address = new Address();
        BeanUtils.copyProperties(addressForm, address);
        List<Address> list = addressDao.findAllByUserIdAndIsSelected(userId, true);
        if (ObjectUtils.isEmpty(list)) {
            address.setIsSelected(true);
        } else {
            address.setIsSelected(false);
        }
        address.setUserId(userId);
        addressDao.saveAndFlush(address);
        return new BaseResult(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg());
    }

    @Override
    public BaseResult setAddress(AddressSelect addressSelect) {
        Address address = addressDao.findOne(addressSelect.getId());
        address.setIsSelected(addressSelect.getIsSelected());
        addressDao.saveAndFlush(address);
        return new BaseResult(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg());
    }

    @Override
    public BaseResult deleteAddress(AddressSelect addressSelect) {
        addressDao.delete(addressSelect.getId());
        return new BaseResult(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg());
    }

    @Override
    public BaseResult wxBack(BackForm backForm) {

        Orders orders = orderDao.findOne(Long.valueOf(backForm.getOut_trade_no()));
        //判断该订单是否为微信支付
        if (orders.getPayType() ==2 ) {
            DecimalFormat df = new DecimalFormat("0");
            String totalFee = df.format(orders.getTotalMoney() * 100);
            SortedMap<Object, Object> params = new TreeMap<>();
            //ID
            params.put("appid", WxPay.appid);
            //商户号
            params.put("mch_id", WxPay.mch_id);
            //随机字符串
            params.put("nonce_str", WXPayUtil.generateNonceStr());
            //操作员id 值为商户号
            params.put("op_user_id", WxPay.mch_id);
            //商户退款单号
            params.put("out_trade_no", backForm.getOut_trade_no());
            //商户订单号
            params.put("out_refund_no", WXPayUtil.generateNonceStr());
            //订单金额
            params.put("total_fee", totalFee);
            //退款金额
            params.put("refund_fee", totalFee);
            String sign = PayCommonUtil.createSign("UTF-8", params, WxPay.secret);
            params.put("sign", sign);
            String requestXML = PayCommonUtil.getRequestXml(params);
            try {
                String request = HttpUtil.doRefund("https://api.mch.weixin.qq.com/secapi/pay/refund", requestXML);
                Map<String, String> map = WXPayUtil.xmlToMap(request);
                if ("SUCCESS".equals(map.get("result_code"))) {
                    orders.setType(6);
                    orderDao.saveAndFlush(orders);
                    return new BaseResult(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg());
                } else {
                    return new BaseResult(2126, "退款失败");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else if (orders.getPayType() == 1) {
            aliPay.refund(backForm.getOut_trade_no(), orders.getTotalMoney().toString(), backForm.getReason());
            orders.setType(6);
            orderDao.saveAndFlush(orders);
            return new BaseResult(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg());
        }
        return null;
    }

    @Override
    public BaseResult changeMyInfo(Long userId, MyInfoForm myInfoForm) {
        User user = userDao.findOne(userId);
        BeanUtils.copyProperties(myInfoForm, user);
        userDao.saveAndFlush(user);
        return new BaseResult(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg());
    }

    @Override
    @Transactional(rollbackOn = Exception.class)
    public void doWxTypeBy1(String out_trade_no, String total_amount) {
        log.info("执行充值");
        PreTrade preTrade = preTradeDao.findByOutTradeNo(out_trade_no);
        System.out.println(preTrade);
        //存在预付订单 是微信支付 且 金额相等 且 没有被处理过
        if (!ObjectUtils.isEmpty(preTrade) && Double.doubleToLongBits(Double.valueOf(total_amount)/100) == Double.doubleToLongBits(preTrade.getAmount()) && !preTrade.getStatus()&&preTrade.getPlatform()==1) {
System.out.println("jinl");
            User user = userDao.findOne(preTrade.getBalanceId());
            user.setMoney(user.getMoney() + (Double.valueOf(total_amount)/100));
            userDao.saveAndFlush(user);


            //生成收入明细
            MoneyDetail detail = new MoneyDetail();
            detail.setType(2);
            detail.setMoney(Double.valueOf(total_amount));
            detail.setIntroduce("充值");
            detail.setUserId(preTrade.getBalanceId());
            moneyDetailDao.saveAndFlush(detail);
        }
        preTrade.setStatus(true);
        preTradeDao.saveAndFlush(preTrade);
    }
}